﻿/*
+-----------------------------------------------------------------------------
|   RaFQuester, RaFQuester/RaFQuester.cs
|   ====================================
|   Created By KinG
|   Version 1.0.7 EXPERIMENTAL
| 	Last updated 2014-06-29
+-----------------------------------------------------------------------------
*/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using Styx;
using Styx.Common;
using Styx.Common.Helpers;
using Styx.CommonBot;
using Styx.CommonBot.AreaManagement;
using Styx.CommonBot.Database;
using Styx.CommonBot.Frames;
using Styx.CommonBot.Inventory;
using Styx.CommonBot.Profiles;
using Styx.CommonBot.POI;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.Pathing;
using Styx.Plugins;
using Styx.WoWInternals;
using Styx.WoWInternals.Misc;
using Styx.WoWInternals.World;
using Styx.WoWInternals.WoWObjects;
using Styx.TreeSharp;

using Sequence = Styx.TreeSharp.Sequence;
using Action = Styx.TreeSharp.Action;
using CommonBehaviors.Actions;
using Levelbot.Actions.Combat;


namespace RaFQuester
{
    public class Main : HBPlugin
    {
		
		public static LocalPlayer Me { get { return StyxWoW.Me; } }
		public static bool IsInGroup { get { return Me.GroupInfo.IsInParty; } }

		public uint partySize 			= 	0;
		public int meLevel 				= 	0;
		public int resetTurnIn 			=	0;
		public long inRange 			= 	0;	
		public bool checkMemberLevel 	= 	false;
		public Random rng				= 	new Random();

		public WoWUnit lastQGtarget		= 	null;
		
		
        public override string Name{ get { return "RaF Quester - EXPERIMENTAL"; } }
		public override string Author{ get { return "KinG"; } }
		public override Version Version{ get { return new Version(1, 0, 7); } }
		public override bool WantButton{ get { return false; } }

        public override void Initialize(){
            Logging.Write(Colors.SkyBlue, Name + " - Loaded Version " + Version);
			partySize = Me.GroupInfo.PartySize;
			meLevel = Me.Level;
			Logging.Write(Colors.SkyBlue, Name + " - We are "+ partySize.ToString() + " party members.");			
        }
		
        public override void Pulse()
        {
			try{
				if(!IsInGroup){
					Logging.Write(Colors.Red, Name + " - I am not in a party, stopping the bot.");
					TreeRoot.Stop(Name);
				}
				partyMemberLevelCheck();
				TargetQGT();
				
			}
			catch (Exception ex){
				Logging.WriteException(ex);
			}
        }
		
		private async void TargetQGT(){
			
			if(partySize != Me.GroupInfo.PartySize){
				partySize = Me.GroupInfo.PartySize;
				Logging.Write(Colors.SkyBlue, Name + " - We are "+ partySize.ToString() +" party members.");
			}

			if(Me.CurrentTarget != null){
				if (Me.CurrentTarget.QuestGiverStatus == QuestGiverStatus.TurnIn){
					if (Me.CurrentTarget.WithinInteractRange){
						WoWMovement.MoveStop();
						if(partyMemberInRange()){
							if(lastQGtarget != Me.CurrentTarget || Me.CurrentTarget == null){
								Logging.Write(Colors.SkyBlue, Name + " - All members are within range.");
								Logging.Write(Colors.SkyBlue, Name + " - Waiting 8 seconds before turning in the quest.");
								inRange = 0;
								//Thread.Sleep(8000);
								await Task.Delay(8000);
								//Will turn in quest here if all arguments are passed.
							}

							if(Me.CurrentTarget != null)
								lastQGtarget = Me.CurrentTarget;
							return;
						}
						else{
							if(Styx.CommonBot.Frames.QuestFrame.Instance.IsVisible || Styx.CommonBot.Frames.GossipFrame.Instance.IsVisible){Styx.CommonBot.Frames.QuestFrame.Instance.Close();Styx.CommonBot.Frames.GossipFrame.Instance.Close();}
							return;
						}
					}
				}
			}
			
			if(lastQGtarget != null){
				if (lastQGtarget.WithinInteractRange){
					if (lastQGtarget.QuestGiverStatus == QuestGiverStatus.TurnIn){
						lastQGtarget.Target();
						TargetQGT();
					}
					if(lastQGtarget.QuestGiverStatus == QuestGiverStatus.Available || lastQGtarget.QuestGiverStatus == QuestGiverStatus.Available || lastQGtarget.QuestGiverStatus == QuestGiverStatus.AvailableRepeatable || lastQGtarget.QuestGiverStatus == QuestGiverStatus.LowLevelAvailable || lastQGtarget.QuestGiverStatus == QuestGiverStatus.None){
						
						int waitTime = rng.Next(5,8);
						Logging.Write(Colors.SkyBlue, Name + " - I am in a " + waitTime.ToString() + " seconds wait period.");
						WoWMovement.MoveStop();
						Me.ClearTarget();
						//Thread.Sleep(waitTime*1000);
						await Task.Delay(waitTime*1000);
						
						if(Me.PartyMembers.Count(player=> player != null && player.IsValid && player.CurrentTarget == lastQGtarget && lastQGtarget != null) > 0 ){
							Logging.Write(Colors.SkyBlue, Name + " - My other party member(s) is still turning in the quest(s), waiting again.");
							resetTurnIn++;
							if(resetTurnIn == 2){
								Logging.Write(Colors.SkyBlue, Name + " - I've waited 2 times extra now, assuming we only were stuck in a loop.");
								resetTurnIn = 1; 
								lastQGtarget = null; 
								return;
							}
							TargetQGT();
						}
					}
				}
				lastQGtarget = null;
			}
			
			return;
        }
		
		private bool partyMemberInRange(){
			
            if (!IsInGroup) return false;
			
			int membersInRange = Me.PartyMembers.Count(player=> player != null && Me.Location.Distance(player.Location) <= 10);
			
			if(membersInRange == partySize && membersInRange != 0){
					return true;
			}
			else{
				if(inRange != (partySize-membersInRange)){
					inRange = (partySize-membersInRange);
					Logging.Write(Colors.SkyBlue, Name + " - " + (partySize-membersInRange).ToString() + " player(s) are out of range.");
				}
				return false;
			}
		}
		
		private void partyMemberLevelCheck(){
		
			//If we are under level 10 and we are different classes remove range check.
			if(lastQGtarget == null){
				// We don't want to reload the profile while we are turning in quests or waiting for other members.
				if(Me.Level == (meLevel+1)){
					Logging.Write(Colors.SkyBlue, Name + " - I have leveled up! I am now level " + Me.Level + ", checking if my party members are the same level.");
					meLevel = Me.Level;
					checkMemberLevel = true;
				}

				if(checkMemberLevel){
					if(Me.PartyMembers.Count(player=> player != null && player.IsValid && player.Level == Me.Level) == partySize && Me.Level >= 10){
						Logging.Write(Colors.SkyBlue, Name + " - We are all the same level, reloading profile to see if we need to change area.");
						ProfileManager.LoadNew(ProfileManager.XmlLocation,true);
						checkMemberLevel = false;
					}
				}
				
			}
			return;
		}
		
		/*private bool knownBadTurnIn(WoWUnit questGiver){
			if(questGiver == "name")
		}*/
		
		
    }
}
